package org.knot.autojmx.api;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.knot.autojmx.annotations.AutoJMX;
import org.knot.autojmx.exception.AutoJMXException;

@AutoJMX
public class ManagerMBean {
	
	protected final static Log logger = LogFactory.getLog(ManagerMBean.class);
	
//	private final static ManagerMBean _managerMbean = new ManagerMBean();
//    private ManagerMBean(){
//    }
//    
//    public static ManagerMBean Instance(){
//        return _managerMbean;
//    }
//	
//	static 
//	{
//		try {
//    		if (null == AutoJMXAPI.getHandlers().get(ManagerMBean.class.getName())){
//    			AutoJMXAPI.Instance().createJMXBean(ManagerMBean.class);
//    		}
//		} catch (Exception e) {
//			logger.error("ManagerMbean pubish to MBean failture , "+e.getMessage());
//		}
//	}
	
	public String getBeanNames()
	{
		StringBuffer strBuf = new StringBuffer();
		for (String key: AutoJMXAPI.getBeans().keySet()){
			strBuf.append(key).append(",");
		}
		return strBuf.toString();
	}
	
	/**
	 *  动态将销毁已发布的JMXBean
	 *  
	 * @param name class name
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws AutoJMXException
	 */
	public void detoryMBean(String name) throws InstantiationException, IllegalAccessException, AutoJMXException
	{
		AutoJMXAPI.Instance().destoryJMXBeanForAPI(name);
		logger.info("detory MBean : " + name + " success");
	}

	
	/**
	 *  动态将单列类发布成JMXBean
	 *  
	 * @param name class name
	 * @throws ClassNotFoundException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws AutoJMXException
	 */
	public void createMBean(String beanName, String className) throws ClassNotFoundException, AutoJMXException  
	{
		String name =  (null == beanName || "".equals(beanName) || "String".equalsIgnoreCase(beanName)) ? className : beanName;
		Object bean = null;
		Class clazz = this.getClass().getClassLoader().loadClass(className);
		
		AutoJMX autoJMX = ManagerMBean.class.getAnnotation(AutoJMX.class);
		if (AutoJMXAPI.getBeans().containsKey(name))
		{
			AutoJMXAPI.Instance().createJMXBean(AutoJMXAPI.getBeans().get(name), name, autoJMX);
		}
		else
		{
			name = "_" + name;
			try {
				bean = clazz.newInstance();
			} catch (Exception ee) {
				//处理静态类
				Method[] methods = clazz.getMethods();
				for (Method method : methods)
				{
					if (method.getReturnType().getName().equals(className) 
							&& (null ==method.getParameterTypes() || method.getParameterTypes().length==0 )
							&& method.toString().indexOf("static")!=-1){
						try {
							bean = method.invoke(clazz, null);
						} catch (IllegalArgumentException e) {
						     continue;
						} catch (InvocationTargetException e) {
							 continue;
						}catch (IllegalAccessException e) {
							 continue;
						}
						if (bean != null) {
							break;
						}
					}
				}
			} 
			finally{
				if (null != bean){
					AutoJMXAPI.Instance().createJMXBean(bean, name, autoJMX);
					logger.info("create MBean : " + className + " success");
				}
			}
		}
	}
}
